/*
 *  Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree.
 */

/* More information about these options at jshint.com/docs/options */
/* jshint browser: true, camelcase: true, curly: true, devel: true,
   eqeqeq: true, forin: false, globalstrict: true, node: true,
   quotmark: single, undef: true, unused: strict */
/* global mozRTCIceCandidate, mozRTCPeerConnection, Promise,
mozRTCSessionDescription, webkitRTCPeerConnection, MediaStreamTrack */
/* exported trace,requestUserMedia */
'use strict';

var RTCPeerConnection = null;
var getUserMedia = null;
var attachMediaStream = null;
var reattachMediaStream = null;
var webrtcDetectedBrowser = null;
var webrtcDetectedVersion = null;

function trace(text) {
    // This function is used for logging.
    if (text[text.length - 1] === '\n') {
        text = text.substring(0, text.length - 1);
    }
    if (window.performance) {
        var now = (window.performance.now() / 1000).toFixed(3);
        console.log(now + ': ' + text);
    } else {
        console.log(text);
    }
}

if (navigator.mozGetUserMedia) {
    console.log('This appears to be Firefox');
    alert('This appears to be Firefox');
    webrtcDetectedBrowser = 'firefox';

    webrtcDetectedVersion =
        parseInt(navigator.userAgent.match(/Firefox\/([0-9]+)\./)[1], 10);

    // The RTCPeerConnection object.
    RTCPeerConnection = function (pcConfig, pcConstraints) {
        // .urls is not supported in FF yet.
        if (pcConfig && pcConfig.iceServers) {
            for (var i = 0; i < pcConfig.iceServers.length; i++) {
                if (pcConfig.iceServers[i].hasOwnProperty('urls')) {
                    pcConfig.iceServers[i].url = pcConfig.iceServers[i].urls;
                    delete pcConfig.iceServers[i].urls;
                }
            }
        }
        return new mozRTCPeerConnection(pcConfig, pcConstraints);
    };

    // The RTCSessionDescription object.
    window.RTCSessionDescription = mozRTCSessionDescription;

    // The RTCIceCandidate object.
    window.RTCIceCandidate = mozRTCIceCandidate;

    // getUserMedia shim (only difference is the prefix).
    // Code from Adam Barth.
    // getUserMedia = navigator.mozGetUserMedia.bind(navigator);
    // navigator.getUserMedia = getUserMedia;

    // Shim for MediaStreamTrack.getSources.
    MediaStreamTrack.getSources = function (successCb) {
        setTimeout(function () {
            var infos = [
                {kind: 'audio', id: 'default', label: '', facing: ''},
                {kind: 'video', id: 'default', label: '', facing: ''}
            ];
            successCb(infos);
        }, 0);
    };

    // Creates ICE server from the URL for FF.
    window.createIceServer = function (url, username, password) {
        var iceServer = null;
        var urlParts = url.split(':');
        if (urlParts[0].indexOf('stun') === 0) {
            // Create ICE server with STUN URL.
            iceServer = {
                'url': url
            };
        } else if (urlParts[0].indexOf('turn') === 0) {
            if (webrtcDetectedVersion < 27) {
                // Create iceServer with turn url.
                // Ignore the transport parameter from TURN url for FF version <=27.
                var turnUrlParts = url.split('?');
                // Return null for createIceServer if transport=tcp.
                if (turnUrlParts.length === 1 ||
                    turnUrlParts[1].indexOf('transport=udp') === 0) {
                    iceServer = {
                        'url': turnUrlParts[0],
                        'credential': password,
                        'username': username
                    };
                }
            } else {
                // FF 27 and above supports transport parameters in TURN url,
                // So passing in the full url to create iceServer.
                iceServer = {
                    'url': url,
                    'credential': password,
                    'username': username
                };
            }
        }
        return iceServer;
    };

    window.createIceServers = function (urls, username, password) {
        var iceServers = [];
        // Use .url for FireFox.
        for (var i = 0; i < urls.length; i++) {
            var iceServer =
                window.createIceServer(urls[i], username, password);
            if (iceServer !== null) {
                iceServers.push(iceServer);
            }
        }
        return iceServers;
    };

    // Attach a media stream to an element.
    attachMediaStream = function (element, stream) {
        console.log('Attaching media stream');
        element.mozSrcObject = stream;
    };

    reattachMediaStream = function (to, from) {
        console.log('Reattaching media stream');
        to.mozSrcObject = from.mozSrcObject;
    };

} // navigator.webkitGetUserMedia is Deprecated.
else if (navigator.getUserMedia || navigator.webkitGetUserMedia) {
    console.log('This appears to be Chrome');
    alert('This appears to be Chrome');

    webrtcDetectedBrowser = 'chrome';
    // Temporary fix until crbug/374263 is fixed.
    // Setting Chrome version to 999, if version is unavailable.
    var result = navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./);
    if (result !== null) {
        webrtcDetectedVersion = parseInt(result[2], 10);
    } else {
        webrtcDetectedVersion = 999;
    }

    // Creates iceServer from the url for Chrome M33 and earlier.
    window.createIceServer = function (url, username, password) {
        var iceServer = null;
        var urlParts = url.split(':');
        if (urlParts[0].indexOf('stun') === 0) {
            // Create iceServer with stun url.
            iceServer = {
                'url': url
            };
        } else if (urlParts[0].indexOf('turn') === 0) {
            // Chrome M28 & above uses below TURN format.
            iceServer = {
                'url': url,
                'credential': password,
                'username': username
            };
        }
        return iceServer;
    };

    // Creates an ICEServer object from multiple URLs.
    window.createIceServers = function (urls, username, password) {
        return {
            'urls': urls,
            'credential': password,
            'username': username
        };
    };

    // The RTCPeerConnection object.
    RTCPeerConnection = function (pcConfig, pcConstraints) {
        return new webkitRTCPeerConnection(pcConfig, pcConstraints);
    };

    // Get UserMedia (only difference is the prefix).
    // Code from Adam Barth.
    // if (!!navigator.getUserMedia == false) {
    //     getUserMedia = navigator.webkitGetUserMedia.bind(navigator);
    //     // navigator.getUserMedia = getUserMedia;
    // } else {
    //     getUserMedia = navigator.getUserMedia.bind(navigator);
    // }

    // Attach a media stream to an element.
    attachMediaStream = function (element, stream) {
        if (typeof element.srcObject !== 'undefined') {
            element.srcObject = stream;
        } else if (typeof element.mozSrcObject !== 'undefined') {
            element.mozSrcObject = stream;
        } else if (typeof element.src !== 'undefined') {
            element.src = URL.createObjectURL(stream);
        } else {
            console.log('Error attaching stream to element.');
        }
    };

    reattachMediaStream = function (to, from) {
        to.src = from.src;
    };
} else {
    console.log('Browser does not appear to be WebRTC-capable');
    alert('Browser does not appear to be WebRTC-capable');
}

//访问用户媒体设备的兼容方法
getUserMedia = function (constraints, success, error) {
    if (navigator.mediaDevices.getUserMedia) {
        //最新的标准API
        navigator.mediaDevices.getUserMedia(constraints).then(success).catch(error);
    } else if (navigator.webkitGetUserMedia) {
        //webkit核心浏览器
        navigator.webkitGetUserMedia(constraints, success, error)
    } else if (navigator.mozGetUserMedia) {
        //firfox浏览器
        navigator.mozGetUserMedia(constraints, success, error);
    } else if (navigator.getUserMedia) {
        //旧版API
        navigator.getUserMedia(constraints, success, error);
    }
};

// Returns the result of getUserMedia as a Promise.
function requestUserMedia(constraints) {
    return new Promise(function (resolve, reject) {
        var onSuccess = function (stream) {
            resolve(stream);
        };
        var onError = function (error) {
            reject(error);
        };

        try {
            getUserMedia(constraints, onSuccess, onError);
        } catch (e) {
            reject(e);
            alert("getUserMedia error.");
        }
    });
}

if (typeof module !== 'undefined') {
    module.exports = {
        RTCPeerConnection: RTCPeerConnection,
        getUserMedia: getUserMedia,
        attachMediaStream: attachMediaStream,
        reattachMediaStream: reattachMediaStream,
        webrtcDetectedBrowser: webrtcDetectedBrowser,
        webrtcDetectedVersion: webrtcDetectedVersion
        //requestUserMedia: not exposed on purpose.
        //trace: not exposed on purpose.
    };
}